package com.hooker.penetration;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.AssetManager;
import android.os.Build;

import com.hooker.base.BaseHooker;
import com.hooker.base.BaseXposedLoader;
import com.hooker.common.Reflection;
import com.hooker.common.StringUtil;
import com.hooker.hook.HookerInject;
import com.hooker.hook.RuleHooker;
import com.hooker.hook.SignatureHook;
import com.hooker.mail.MailInfo;
import com.hooker.mail.SendMailUtil;
import com.hooker.settings.Setting;
import com.hooker.settings.SettingHelper;
import com.hooker.util.Constants;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import dalvik.system.DexClassLoader;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class PluginPenetration extends BaseXposedLoader {

    private Set<String> pgSets;

    public PluginPenetration(Context context, XC_LoadPackage.LoadPackageParam loadParams) {
        super(context, loadParams);
        pgSets = (Set<String>) loadParams.getObjectExtra("package_set");
        log("pgSet=" + pgSets);
    }

    @Override
    public void hook(Object... calls) {
        log("hook network pg=");

        BaseHooker.UnXposedHooker xposedHooker = new BaseHooker.UnXposedHooker(context, loadParams);
        xposedHooker.hook();

        BaseHooker.NetWorkHooker netWork = new BaseHooker.NetWorkHooker(context, loadParams);
        netWork.hook();

        BaseHooker.ContextHooker contextHooker = new BaseHooker.ContextHooker(context, loadParams);
        contextHooker.hook();

        BaseHooker.ActivityHooker activityHooker = new BaseHooker.ActivityHooker(context, loadParams);
        activityHooker.hook();

        BaseHooker.ServiceHooker serviceHooker = new BaseHooker.ServiceHooker(context, loadParams);
        serviceHooker.hook();

        BaseHooker.ContentProviderHooker contentProviderHooker = new BaseHooker.ContentProviderHooker(context, loadParams);
        contentProviderHooker.hook();

        BaseHooker.BroadCastHooker broadCastHooker = new BaseHooker.BroadCastHooker(context, loadParams);
        broadCastHooker.hook();

        BaseHooker.SharedPreferenceHooker spHooker = new BaseHooker.SharedPreferenceHooker(context, loadParams);
        spHooker.hook();

        BaseHooker.FileHooker fileHooker = new BaseHooker.FileHooker(context, loadParams);
        fileHooker.hook();

        BaseHooker.UriHooker uriHooker = new BaseHooker.UriHooker(context, loadParams);
        uriHooker.hook();
//
        BaseHooker.JsonHooker jsonHooker = new BaseHooker.JsonHooker(context, loadParams);
        jsonHooker.hook();

        BaseHooker.SqliteHooker sqliteHooker = new BaseHooker.SqliteHooker(context, loadParams);
        sqliteHooker.hook();

        BaseHooker.WebViewHooker webViewHooker = new BaseHooker.WebViewHooker(context, loadParams);
        webViewHooker.hook();

        BaseHooker.PermissionHooker permissionHooker = new BaseHooker.PermissionHooker(context, loadParams);
        permissionHooker.hook(new BaseHooker.CallBack() {
            @Override
            public Object call(Object object) {
                if (object != null && object instanceof List) {
                    List<String> permissions = (List<String>) object;
                    if (permissions != null && !permissions.isEmpty()) {
                        StringBuilder builder = new StringBuilder();
                        StringUtil.join(builder, permissions, "\n");

                        Set<String> addresses = new HashSet<>();

                        List<String> emails = SettingHelper.getInfo(context, Constants.MAIL_TAG_ID);
                        addresses.addAll(emails);

                        if (addresses != null && addresses.size() > 0) {
                            MailInfo info = new MailInfo.Builder()
                                    .setContent(builder.toString())
                                    .setSubject("渗透异常提醒-" + loadParams.packageName)
                                    .setToAddress(addresses)
                                    .build();
                            SendMailUtil.send(info);
                        }
                    }
                }
                return null;
            }
        });

        final RuleHooker ruleHooker = RuleHooker.getInstance();
        ruleHooker.setContext(context);
        ruleHooker.setLoadParams(loadParams);
        ruleHooker.hook();

        //hook 会有问题
//        BaseHooker.StringHooker stringHooker = new BaseHooker.StringHooker(context, loadParams);
//        stringHooker.hook();

        HookerInject inject = new HookerInject(context, loadParams);
        inject.hook(pgSets);

        new SignatureHook(context, loadParams).hook();
    }
}
